package com.dgut.courses_selecting_sys.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dgut.courses_selecting_sys.constants.RedisKey;
import com.dgut.courses_selecting_sys.constants.UserConstants;
import com.dgut.courses_selecting_sys.entity.User;
import com.dgut.courses_selecting_sys.mapper.UserMapper;
import com.dgut.courses_selecting_sys.mapper.UserRoleMapper;
import com.dgut.courses_selecting_sys.service.IUserService;
import com.dgut.courses_selecting_sys.shiro.service.SysPasswordService;
import com.dgut.courses_selecting_sys.utils.RedisUtil;
import com.dgut.courses_selecting_sys.utils.ShiroUtils;
import com.dgut.courses_selecting_sys.utils.core.Convert;
import com.dgut.courses_selecting_sys.utils.core.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yuec
 * @since 2020-07-23
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysPasswordService sysPasswordService;

    @Autowired
    private UserRoleMapper userRoleMapper;


    //根据 学号/学工号 查找用户
    @Override
    @Cacheable(cacheNames = {"users"}, key = "#loginName", unless = "#result==null")
    public User selectUserByLoginName(String loginName) {
        Map<String, Object> map = new HashMap<>();
        map.put("login_name", loginName);
        List<User> users = userMapper.selectByMap(map);
        if (users.size() == 0) {
            return null;
        } else {
            return users.get(0);
        }
    }

    //更新账户信息
    @Override
    @Caching(evict = {@CacheEvict(value = "ListStuByDeptId", key = "#user.deptId"),
            @CacheEvict(value = "ListTeachByDeptId", key = "#user.deptId"),
            @CacheEvict(value = "users",key = "#user.loginName")},
            put = @CachePut(value = {"users"}, key = "#user.loginName", unless = "#result==null"))
    public User updateUser(User user) {
        if (userMapper.updateById(user) == 1) {
            return user;
        } else {
            return null;
        }
    }


    //根据 电话号码 查找用户
    @Override
    public User selectUserByPhoneNumber(String phoneNumber) {
        Map<String, Object> map = new HashMap<>();
        map.put("phonenumber", phoneNumber);
        List<User> users = userMapper.selectByMap(map);
        if (users.size() == 0) {
            return null;
        } else {
            return users.get(0);
        }
    }

    //根据 电子邮箱 查询客户
    @Override
    public User selectUserByEmail(String email) {
        Map<String, Object> map = new HashMap<>();
        map.put("email", email);
        List<User> users = userMapper.selectByMap(map);
        if (users.size() == 0) {
            return null;
        } else {
            return users.get(0);
        }
    }

    //查看 用户学号/学工号是否唯一
    @Override
    public String checkLoginNameUnique(String loginName) {
        Map<String, Object> map = new HashMap<>();
        map.put("login_name", loginName);
        List<User> users = userMapper.selectByMap(map);
        if (users.size() == 0) {
            return "0";
        } else {
            return "1";
        }
    }

    //注册 新用户
    @Override
    @Cacheable(value = {"users"}, key = "#user.loginName", unless = "#result==null")
    public boolean registerUser(User user) {
        int result = userMapper.insert(user);
        return Convert.toBool(result);
    }

    //恢复用户
    @Override
    public boolean recoverUser(Long userId) {
        User user = new User();
        user.setUserId(userId);
        user.setStatus("0");
        User userDB = userMapper.selectById(userId);
        //删除redis记录
        redisUtil.del(RedisKey.USERS + userDB.getLoginName());
        log.warn("账号恢复调用::账号id编号->" + userId);
        return Convert.toBool(userMapper.updateById(user));
    }

    //停用用户
    @Override
    public boolean disableUser(Long userId) {
        User user = new User();
        user.setUserId(userId);
        user.setStatus("1");
        User userDB = userMapper.selectById(userId);
        //删除redis记录
        redisUtil.del(RedisKey.USERS + userDB.getLoginName());
        log.warn("账号停用调用::账号id编号->" + userId);
        return Convert.toBool(userMapper.updateById(user));
    }

    //修改密码
    @Override
    public boolean resetPassword(Long userId, String password) {
        User user = userMapper.selectById(userId);
        //删除redis记录
        redisUtil.del(RedisKey.USERS + user.getLoginName());
        User updateUser = new User();
        updateUser.setUserId(userId);
        updateUser.setSalt(ShiroUtils.randomSalt());
        if (StringUtils.isEmpty(password)) {
            password = UserConstants.DEFAULT_PASSWORD;
        } else {
            int lenth = password.length();
            if (lenth < UserConstants.PASSWORD_MIN_LENGTH || lenth > UserConstants.PASSWORD_MAX_LENGTH) {
                //密码长度不规范
                return false;
            }
        }
        password = sysPasswordService.encryptPassword(user.getLoginName(), password, updateUser.getSalt());
        updateUser.setPassword(password);
        userMapper.updateById(updateUser);
        log.info("账号密码修改::修改人账号->{}" + ShiroUtils.getSysUser().getLoginName());
        return true;
    }

    //创建账号
    @Override
    public User createUser(User user, int roleId) {
        try {
            user.setSalt(ShiroUtils.randomSalt());
            user.setPassword(sysPasswordService.encryptPassword(user.getLoginName(), UserConstants.DEFAULT_PASSWORD, user.getSalt()));
            if (UserConstants.USER_NAME_NOT_UNIQUE == userMapper.checkLoginNameUnique(user.getLoginName())) {
                return user;
            }
            userMapper.insert(user);
            User userdb = userMapper.selectUserByLoginName(user.getLoginName());
            userRoleMapper.insertOne(userdb.getUserId(), roleId);
            return null;
        } catch (Exception e) {
            return user;
        }
    }
}
